package com.mall.shopping.services;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mall.commons.doc.ItemDoc;
import com.mall.commons.tool.utils.ObjectIsEmptyUtils;
import com.mall.shopping.IProductService;
import com.mall.shopping.constants.ShoppingRetCode;
import com.mall.shopping.converter.PanelConverter;
import com.mall.shopping.converter.ProductConverter;
import com.mall.shopping.converter.ProductDetailConverter;
import com.mall.shopping.dal.entitys.Item;
import com.mall.shopping.dal.entitys.Panel;
import com.mall.shopping.dal.persistence.item.ItemMapperByMP;
import com.mall.shopping.dal.persistence.item.PanelMapperByMP;
import com.mall.shopping.dto.*;
import org.apache.dubbo.config.annotation.Service;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 类<code>Doc</code>用于：TODO
 *
 * @author Acher
 * @version 1.0
 * @date 2021-10-31
 */
@Service
public class IProductServiceImpl implements IProductService {

    @Autowired
    ItemMapperByMP itemMapper;
    @Autowired
    ProductDetailConverter productDetailConverter;
    @Autowired
    ProductConverter productConverter;
    @Autowired
    PanelMapperByMP panelMapper;
    @Autowired
    PanelConverter panelConverter;
    @Autowired
    RestHighLevelClient client;

    @Override
    public ProductDetailResponse getProductDetail(ProductDetailRequest req) {
        ProductDetailResponse resp = new ProductDetailResponse();
        try {
            req.requestCheck();
            SearchRequest request = new SearchRequest("goods");
            request.source().query(QueryBuilders.termQuery("id", req.getId()));
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            SearchHit hit = response.getHits().getHits()[0];
            ItemDoc itemDoc = new ObjectMapper().readValue(hit.getSourceAsString(), ItemDoc.class);
            ProductDetailDto productDetailDto = productDetailConverter.itemDoc2ProductDetailDto(itemDoc);
//            Item item = itemMapper.selectItemById(req.getId());
//            ProductDetailDto productDetailDto = productDetailConverter.itemDo2ProductDetailDto(item);
            resp.setCode(ShoppingRetCode.SUCCESS.getCode());
            resp.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            resp.setProductDetailDto(productDetailDto);
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCode(ShoppingRetCode.DB_EXCEPTION.getCode());
            resp.setMsg(ShoppingRetCode.DB_EXCEPTION.getMessage());
        }
        return resp;
    }

    @Override
    public AllProductResponse getAllProduct(AllProductRequest req) {
        AllProductResponse resp = new AllProductResponse();
        try {
//            req.requestCheck();
            // 1.准备Request
            SearchRequest request = new SearchRequest("goods");
            SearchResponse searchResponse = getSearchResponse(req, request);
            // 4.处理结果
            SearchHits searchHits = searchResponse.getHits();
            long total = searchHits.getTotalHits();
            SearchHit[] hits = searchHits.getHits();
            ObjectMapper mapper = new ObjectMapper();
            List<ProductDto> productDtos = new ArrayList<>();
            List<ItemDoc> itemDocs = new ArrayList<>();
            for (SearchHit hit : hits) {
                String json = hit.getSourceAsString();
                itemDocs.add(mapper.readValue(json, ItemDoc.class));
            }
            itemDocs.forEach(itemDoc -> productDtos.add(new ProductDto(itemDoc)));
            resp.setCode(ShoppingRetCode.SUCCESS.getCode());
            resp.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            resp.setTotal(total);
            resp.setData(productDtos);
        } catch (Exception e) {
            e.printStackTrace();
            resp.setCode(ShoppingRetCode.DB_EXCEPTION.getCode());
            resp.setMsg(ShoppingRetCode.DB_EXCEPTION.getMessage());
        }
        return resp;
    }

    private SearchResponse getSearchResponse(AllProductRequest req, SearchRequest request) throws IOException {
        // 2.准备DSL，核心api：source(),QueryBuilders
        if (!ObjectIsEmptyUtils.integerIsEmpty(req.getPriceLte()) && !ObjectIsEmptyUtils.integerIsEmpty(req.getPriceGt())) {
            request.source()
                    .query(QueryBuilders.boolQuery()
                            .filter(QueryBuilders.rangeQuery("price")
                                    .gte(req.getPriceGt())
                                    .lte(req.getPriceLte())));
        } else if (!ObjectIsEmptyUtils.integerIsEmpty(req.getPriceLte())) {
            request.source()
                    .query(QueryBuilders.boolQuery()
                            .filter(QueryBuilders.rangeQuery("price")
                                    .lte(req.getPriceLte())));
        } else if (!ObjectIsEmptyUtils.integerIsEmpty(req.getPriceGt())) {
            request.source()
                    .query(QueryBuilders.boolQuery()
                            .filter(QueryBuilders.rangeQuery("price")
                                    .gte(req.getPriceGt())));
        }
        if (!ObjectIsEmptyUtils.stringIsEmpty(req.getSort())) {
            if (Integer.parseInt(req.getSort()) == 1) {
                request.source().sort("price");
            } else if (Integer.parseInt(req.getSort()) == -1) {
                request.source().sort("price", SortOrder.DESC);
            }
        }
        request.source()
                .from((req.getPage() - 1) * req.getSize())
                .size(req.getSize());
        // 3.发送
        SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
        return searchResponse;
    }

    @Override
    public RecommendResponse getRecommendGoods() {
        RecommendResponse response = new RecommendResponse();
        try {
            List<Panel> panels = panelMapper.selectAllPanel();
            List<Panel> recommend = panels.stream()
                    .filter(item -> item.getName().equals("热门推荐"))
                    .collect(Collectors.toList());
            List<PanelDto> panelDtos = panelConverter.panelDO2DTO(recommend);
            response.setCode(ShoppingRetCode.SUCCESS.getCode());
            response.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            response.setPanelContentItemDtos(panelDtos);
        } catch (Exception e) {
            e.printStackTrace();
            response.setCode(ShoppingRetCode.DB_EXCEPTION.getCode());
            response.setMsg(ShoppingRetCode.DB_EXCEPTION.getMessage());
        }
        return response;
    }
}
